<?php
/**
 * Cache Class
 *
 * @author @@AUTHOR@@
 * @copyright @@AUTHOR@@ @@YEAR@@
 * @version @@VERSION@@
 * @package Extensions
 * @subpackage Low-Cal_Vanilla
 * @license  @@LICENCE_URL@@ @@LICENCE@@
 *
 * $Id: Class.Cache.php 303 2008-09-28 21:13:41Z dinoboff $
 * $HeadURL$
 */


include_once('Class.File.php');

/**
 * Cache data in files
 * @package Extensions
 * @subpackage Low-Cal_Vanilla
 */

class LowCalVanilla_Cache {
	var $_Dir;
	var $_Ext;
	var $Context;

	function LowCalVanilla_Cache(&$Context) {
		$this->Context =& $Context;

		if (is_dir($Context->Configuration['LOWCALVANILLA_CACHE_DIR'])
		&&  is_writable($Context->Configuration['LOWCALVANILLA_CACHE_DIR'])
		) {
			$this->_Dir = $Context->Configuration['LOWCALVANILLA_CACHE_DIR'];
			$this->_Ext = $Context->Configuration['LOWCALVANILLA_CACHE_EXT'];
		}
	}

	function _SetHeader($Header) {
		return pack('CL', $Header['Serialized'], $Header['TTL']);
	}

	function _GetHeader($PackedHeader) {
		return unpack('C1Serialized/L1TTL', $PackedHeader);
	}

	function _Save(&$File, $Data, $TTL) {
		$return = false;

		if ($TTL) {
			$TTL = time() + $TTL;
		}
		$Header = array(
			'Serialized' => 0,
			'TTL' => $TTL);
		if (!is_string($Data)) {
			$Data = serialize($Data);
			$Header['Serialized'] = 1;
		}
		if ($PackedHeader = $this->_SetHeader($Header)) {
			$return = $File->SetContents($PackedHeader . $Data);
		}
		$File->Close();
		return $return;
	}

	/**
	 * Enter description here...
	 *
	 * @param unknown_type $Key
	 * @return LowCalVanilla_File
	 */
	function _GetFile($Key) {
		$Path = $this->_Dir . '/' . md5($Key) . $this->_Ext;
		return new LowCalVanilla_File($this->Context, $Path);
	}

	function Add($Key, $Data, $TTL = 0) {
		$File = $this->_GetFile($Key);
		// Check the data is not already set
		if ($File->Exist()) {
			$Header = array();
			$File->Open();
			if ($PackedHeader = $File->Read(5)) {
				$Header = $this->_GetHeader($PackedHeader);
			}
			// check if header is outdated
			if(array_key_exists('TTL', $Header)
				&& ($Header['TTL'] === 0
					|| time() < $Header['TTL'])
			) {
				return false;
			}
		}
		return $this->_Save($File, $Data, $TTL);
	}

	function ClearCache() {
		if ($handle = opendir($this->_Dir)) {
			while (false !== ($Item = readdir($handle))) {
				if ( !is_dir($this->_Dir . '/' . $Item)
					&& strrchr($Item, $this->_Ext)
				) {
					@unlink($this->_Dir . '/' . $Item);
				}
			}
			return true;
		} else {
			return false;
		}

	}

	function Delete($Key) {
		if ($File = $this->_GetFile($Key)) {
			return $File->Unlink();
		}
		return false;
	}

	function Fletch($Key) {
		$Header = null;
		$Content = '';
		$File = $this->_GetFile($Key);
		$File->Open();
		if ($PackedHeader = $File->Read(5, false)) {
			$Header = $this->_GetHeader($PackedHeader);
		}
		if ($Header
			&& (!$Header['TTL']
				|| ($Header['TTL']
					&& time() < $Header['TTL'])
			)
		) {
			$Content = $File->ReadThru();
			if ($Header['Serialized']) {
				$Content = @unserialize($Content);
			}
		}
		$File->Close();
		return $Content;
	}

	function GetLastModification($Key) {
		$File = $this->_GetFile($Key);
		return $File->GetLastModification();
	}

	function Store($Key, $Data, $TTL = 0) {
		$File = $this->_GetFile($Key);
		$return = $this->_Save($File, $Data, $TTL);
		$File->Close();
		return $return;
	}
}